home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 10.4 KB | 424 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------------
- // UFailure.cp
- // Copyright © 1985-96 by Apple Computer, Inc. All rights reserved.
- //----------------------------------------------------------------------------------------
-
- #ifndef __UFAILURE__
- #include "UFailure.h"
- #endif
-
- // MacApp
-
- #ifndef __UDEBUG__
- #include "UDebug.h"
- #endif
-
- #ifndef __UCOREUTILITIES__
- #include "UCoreUtilities.h"
- #endif
-
- #ifndef __UTHEDEBUGGER__
- #include "UTheDebugger.h"
- #endif
-
- // Toolbox
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __PROCESSES__
- #include <Processes.h>
- #endif
-
- // ANSI
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
-
- //----------------------------------------------------------------------------------------
- // static data members
- //----------------------------------------------------------------------------------------
- FailInfoPtr FailInfo::gTopHandler;
-
-
- //----------------------------------------------------------------------------------------
- // GLOBAL Variables
- //----------------------------------------------------------------------------------------
-
- #if qDebug
- static MAName pWho; // used serially. Avoids putting it on stack
- #endif
-
- //----------------------------------------------------------------------------------------
- // Assertion:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void Assertion(const Boolean condition,
- const CStr255&
- #if qDebug
- description
- #endif
- )
- {
- if (!condition)
- {
- #if qDebug
- GetCallersMethodName(pWho);
- fprintf(stderr, "Assertion failed in " + pWho + ": " + description + "\n");
- #endif
- Failure(minErr, 0);
- }
- } // Assertion
-
- //----------------------------------------------------------------------------------------
- // FailMemError:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- long BuildMessage(short lowWord, short highWord)
- {
- return ((long)highWord << 16) | lowWord;
- }
-
- //----------------------------------------------------------------------------------------
- // FailMemError:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void FailMemError()
- {
- OSErr e = MemError();
-
- if (e != noErr)
- Failure(e, 0);
- } // FailMemError
-
- //----------------------------------------------------------------------------------------
- // FailNewMessage:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void FailNewMessage(OSErr error,
- long oldMessage,
- long newMessage)
- {
- Failure(error, oldMessage ? oldMessage : newMessage);
- } // FailNewMessage
-
- //----------------------------------------------------------------------------------------
- // FailNIL:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void FailNIL(void* p)
- {
- if (!p)
- Failure(memFullErr, 0);
- } // FailNIL
-
- //----------------------------------------------------------------------------------------
- // FailNILResource:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void FailNILResource(Handle r)
- {
- if (!r)
- {
- OSErr e = ResError();
- if (e == noErr)
- e = resNotFound;
- Failure(e, 0);
- }
- } // FailNILResource
-
- //----------------------------------------------------------------------------------------
- // FailOSErr:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void FailOSErr(OSErr error)
- {
- if (error != noErr)
- Failure(error, 0);
- } // FailOSErr
-
- //----------------------------------------------------------------------------------------
- // FailOSAError:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void FailOSAError(long error)
- {
- if (error != noErr)
- Failure((OSErr) error, 0);
- } // FailOSAError
-
- //----------------------------------------------------------------------------------------
- // FailResError:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void FailResError()
- {
- OSErr e = ResError();
-
- if (e != noErr)
- Failure(e, 0);
- } // FailResError
-
- //----------------------------------------------------------------------------------------
- // Failure:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void Failure(OSErr error, long message)
- {
- FailInfoPtr pf = FailInfo::gTopHandler;
- if (pf)
- {
- do
- {
- // pop the stack first, because calling the handler is likely to result in a call
- // to Failure
- FailInfo::gTopHandler = pf->nextInfo;
-
- #if qDebug
- if (pf->installed && pf->cleanupProc)
- ProgramBreak("Use SetCleanupProc or Try, not both");
-
- pf->installed = FALSE;
- if (DebugCanWriteLn() && (((error != noErr) && (error != userCanceledErr)) || gIntenseDebugging))// only show 0 errors if _really_ looking
- {
- GetCallersMethodName(pWho);
- fprintf(stderr, "Failure signaled by: %s\n", (const char*)pWho);
- fprintf(stderr, " error: %1d message: %1d (%1d/%1d)\n", error, message, message >> 16, message & 0x0000FFFF);
- }
- #endif
-
- pf->error = error;
- pf->message = message;
-
- // Go execute the failure handler
-
- if (pf->cleanupProc)
- (*(pf->cleanupProc))(pf->cleanupContext);
- else
- longjmp(pf->savedState, 0);
-
- // If a cleanupProc was specified, we'll fall through to here and loop
- // to the next failure handler (less overhead than recursing)
- }
- while ((pf = FailInfo::gTopHandler) != NULL);
- }
- else
- {
- #if qDebug
- ProgramBreak("Failure called, but no handler!");
- #endif
- // The following ExitToShell allows the application to fail somewhat gracefully
- // in the case that an allocation request has failed during static initialization.
- ExitToShell();
- }
- } // Failure
-
- //----------------------------------------------------------------------------------------
- // ProgramBreak:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void ProgramBreak(const CStr255& grievance)
- {
- CStr255 report = grievance + "\n";
-
- #if qDebug || qTheDebugger
- #if !defined(__MWERKS__) || (TypeOfCWDebugging != kxUseSTE)
- fflush(stderr);
- #endif
- #endif
-
- #if qDebug
- if ((gCurrentDebugger == kxSourceBug) || (gCurrentDebugger == kxVooDoo) ||
- (gCurrentDebugger == kxSade))
- SysBreakFunc(report);
- else
- #endif
- #if qTheDebugger
- if (gExtDbgr_Info.isBeingDebugged || TheDbgr_IsInstalled())
- SysBreakFunc(report);
- else
- #endif
- DebugStr(report);
- }
-
- //----------------------------------------------------------------------------------------
- // ProgramReport:
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void ProgramReport(const CStr255& grievance,
- const Boolean breakInDebugger)
- {
- CStr255 report = grievance + "\n";
-
- #if qDebug || qTheDebugger
- #if !defined(__MWERKS__) || (TypeOfCWDebugging != kxUseSTE)
- fflush(stderr);
- #endif
- #endif
-
- #if qDebug
- if ((gCurrentDebugger == kxSourceBug) || (gCurrentDebugger == kxVooDoo) ||
- (gCurrentDebugger == kxSade))
- {
- if (breakInDebugger)
- SysBreakStr(report);
- else
- SysBreakFunc(report);
- }
- else
- #endif
- #if qTheDebugger
- if (gExtDbgr_Info.isBeingDebugged || TheDbgr_IsInstalled())
- {
- if (breakInDebugger)
- SysBreakStr(report);
- else
- SysBreakFunc(report);
- }
- else
- #endif
- {
- if (!breakInDebugger)
- report += ";g";
- DebugStr(report);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FailInfo::~FailInfo
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- #if qDebug
- FailInfo::~FailInfo()
- {
- if (installed)
- ProgramBreak("You forgot to call success for your failure handler");
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // FailInfo::Install
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- FailInfo* FailInfo::Install()
- {
- nextInfo = gTopHandler;
- gTopHandler = this;
- #if qDebug
- installed = TRUE;
- #endif
-
- return this;
- }
-
- //----------------------------------------------------------------------------------------
- // FailInfo::Success
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- #if qDebug
- void FailInfo::Success()
- {
- if (gTopHandler != this)
- {
- CStr255 msg;
-
- fprintf(stderr, "gTopHandler: %p, parameter: %p\n", gTopHandler, this);
- msg = "Problem with Success: ";
- if (HandlerExists())
- msg += "too few ";
- else
- msg += "too many ";
- msg += "calls to Success";
- ProgramBreak(msg);
- }
-
- installed = FALSE;
-
- gTopHandler = nextInfo;
- } // Success
- #endif
-
-
- //----------------------------------------------------------------------------------------
- // FailInfo::Reset
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void FailInfo::Reset()
- {
- nextInfo = NULL;
- cleanupProc = NULL;
- cleanupContext = NULL;
- message = 0;
- error = noErr;
- #if qDebug
- installed = FALSE;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FailInfo::SetCleanupProc
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- void FailInfo::SetCleanupProc(FailureCleanupProc theCleanupProc, void* itsContext)
- {
- nextInfo = gTopHandler;
- gTopHandler = this;
- cleanupProc = theCleanupProc;
- cleanupContext = itsContext;
- }
-
- //----------------------------------------------------------------------------------------
- // FailInfo::HandlerExists
- //----------------------------------------------------------------------------------------
- #pragma segment MAFailureRes
-
- Boolean FailInfo::HandlerExists() const
- {
- FailInfoPtr pf = gTopHandler;
-
- while (pf)
- {
- if (pf == this)
- return TRUE;
- pf = pf->nextInfo;
- }
-
- return FALSE;
- } // HandlerExists
-
- //----------------------------------------------------------------------------------------
- // End of UFailure.cp
-
- #pragma segment Inline
-